// 杜教筛
// 测试链接 ：https://www.luogu.com.cn/problem/P3768
// 相关帖子 ：https://www.cnblogs.com/dx123/p/16995109.html
// 相关帖子 ：https://oi-wiki.org/math/number-theory/du/
// 提交以下的code，可以直接通过

#include <bits/stdc++.h>

using namespace std;

#define ll long long
#define LL ll
const int MAXN = 5000000;
bool visited[MAXN];
int cnt;
int prime[MAXN];
int phi[MAXN];
ll P, n, sum[MAXN], inv;
unordered_map<ll, ll> mp;

ll qucik(ll a, ll b)
{
    ll ans = 1;
    while(b)
    {
        if(b & 1) ans = ans * a % P;
        a = a * a % P;
        b >>= 1;
    }
    return ans;
}

void init()
{
    inv = qucik(6, P - 2);
    phi[1] = 1;
    for(int i = 2; i < MAXN; ++i)
    {
        if(!visited[i])
        {
            prime[++cnt] = i;
            phi[i] = i - 1;
        }
        for(int j = 1; i * prime[j] < MAXN; ++j)
        {
            visited[i * prime[j]] = true;
            if(i % prime[j] == 0)
            {
                phi[i * prime[j]] = prime[j] * phi[i];
                break;
            }
            phi[i * prime[j]] = (prime[j] - 1) * phi[i];
        }
    }
    for(int i = 1; i < MAXN; ++i)
    {
        sum[i] = (sum[i - 1] + 1LL * i * i % P * phi[i] % P) % P;
    }
}

ll S2(ll x)
{
    x %= P;
    return x * (x + 1) % P * (2 * x + 1) % P * inv % P;
}

ll S3(ll x)
{
    x %= P;
    return ((x * (x + 1) / 2) % P) * ((x * (x + 1) / 2) % P) % P;
}

ll Sn(ll x)
{
    if(x < MAXN) return sum[x];
    if(mp[x]) return mp[x];
    ll ans = S3(x);
    for(ll l = 2, r; l <= x; l = r + 1)
    {
        r = x / (x / l);
        ans = (ans - (S2(r) - S2(l - 1)) % P * Sn(x / l) % P + P) % P;
    }
    return mp[x] = ans;
}

ll compute()
{
    ll ans = 0;
    for(ll l = 1, r; l <= n; l = r + 1)
    {
        r = n / (n / l);
        ans = (ans + (Sn(r) - Sn(l - 1)) % P * S3(n / l) % P + P) % P;
    }
    return ans;
}

int main()
{
    scanf("%lld%lld", &P, &n);
    init();
    printf("%lld\n", compute());

    return 0;
}